package com.zoweunion.mechanic.service.app.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zoweunion.mechanic.dao.FacilitatorPersonnelRelationDao;
import com.zoweunion.mechanic.dao.TSSsVehicleModelDao;
import com.zoweunion.mechanic.model.things.ThingsData;
import com.zoweunion.mechanic.plugins.redis.RedisUtil;
import com.zoweunion.mechanic.service.TSSsVehicleModelService;
import com.zoweunion.mechanic.service.base.BaseService;
import com.zoweunion.mechanic.dao.app.ScreenDataMapper;
import com.zoweunion.mechanic.dao.app.ToolCarDataMapper;
import com.zoweunion.mechanic.service.app.ScreenDataService;
import com.zoweunion.mechanic.service.impl.FacilitatorPersonnelRelationServiceImpl;
import com.zoweunion.mechanic.service.impl.TSSsVehicleModelServiceImpl;
import com.zoweunion.mechanic.util.Orgin;
import com.zoweunion.mechanic.util.constants.Constants;
import com.zoweunion.mechanic.util.HttpClient;
import com.zoweunion.mechanic.util.MyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 大屏数据service实现类
 * @author rentianfeng
 */
@Service
@SuppressWarnings("unchecked")
@Transactional
public class ScreenDataServiceImpl extends BaseService implements ScreenDataService {
    @Autowired
    private ScreenDataMapper screenDataMapper;
    @Autowired
    private ToolCarDataMapper toolCarDataMapper;
    @Autowired
    private TSSsVehicleModelDao modelDao;
    @Autowired
    private TSSsVehicleModelServiceImpl tsSsVehicleModelService;
    @Autowired
    private FacilitatorPersonnelRelationServiceImpl relationService;
    @Autowired
    private FacilitatorPersonnelRelationDao relationDao;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 获取全部车辆实时位置
     * @return
     * @throws MyException
     */
    @Override
    public Map<String, Object> getScreenData(Map<String, Object> reqMap) throws MyException {

        Map<String, Object> resultMap = new HashMap<>();
        //是否开启虚拟点添加
        int i = screenDataMapper.selectPointConfiguration();
        if (i==0){//不添加虚拟
            tsSsVehicleModelService.ifDemo(reqMap);
            int serverCount=0;
            if (Orgin.getString(reqMap,"demoType").equals("0")){
                List<String> s_id = relationDao.selectCountBySid(Orgin.getString(reqMap, "s_id"));
                serverCount=s_id.size();
            }else {
                serverCount= screenDataMapper.getServerCount();
            }
            //服务商数量
            resultMap.put("serverCount",serverCount);
            //总工时 总油耗
            Map<String, Object> mapCount = modelDao.selectAverage(reqMap);
            resultMap.put("workHourSum", Orgin.getDoubleValue(mapCount,"workHourSum"));
            resultMap.put("fuelSum", Orgin.getDoubleValue(mapCount,"fuelSum"));
            //在线
            List<Map<String, Object>> carList = modelDao.selectCar(reqMap);
            resultMap.put("carOnline",carList.size());
            //合同数量(车辆数)
            List<Long> longs = modelDao.selectThingsCount();


            long sum = longs.stream().mapToLong(x -> x.longValue()).sum();
            resultMap.put("carAll", sum);
            //上线数量
            resultMap.put("onlineUp", modelDao.selectOnline(reqMap));
            //工作中
            resultMap.put("working", carList.stream()
                    .filter(o -> Orgin.getIntValue(o, "device_status") == 1).count());
            //工作新
            resultMap.put("workingNew", carList.stream()
                    .filter(o -> Orgin.getIntValue(o, "status") == 1).count());
            //故障
            Long faultCount = carList.stream()
                    .filter(o -> Orgin.getIntValue(o, "fault_status") == 1).count();
            resultMap.put("faultCount", faultCount);
            reqMap.put("device_status",1);
            List<Map<String, Object>> mapList = modelDao.selectPoints(reqMap);
            for (Map<String, Object> item : mapList) {
                double[] myList = new double[2];
                myList[0]=Orgin.getDoubleValue(item,"GPSlongitude");
                myList[1]=Orgin.getDoubleValue(item,"GPSlatitude");
                item.put("lnglat",myList);
                item.remove("GPSlongitude");
                item.remove("GPSlatitude");
            }
            resultMap.put("onlineCarType1",mapList);
            resultMap.put("onlineCarType1Size",mapList.size());
            reqMap.put("device_status",2);
            List<Map<String, Object>> mapLis2  = modelDao.selectPoints(reqMap);
            for (Map<String, Object> item : mapLis2) {
                double[] myList1 = new double[2];
                myList1[0]=Orgin.getDoubleValue(item,"GPSlongitude");
                myList1[1]=Orgin.getDoubleValue(item,"GPSlatitude");
                item.put("lnglat",myList1);
                item.remove("GPSlongitude");
                item.remove("GPSlatitude");
            }
            resultMap.put("offlineCarType1",mapLis2);
            resultMap.put("offlineCarType1Size",mapLis2.size());
        }
        // 开启虚拟的数据大屏，目前直接乘以9
        else {

            int serverCount = screenDataMapper.getServerCount();
            //服务商数量
            resultMap.put("serverCount",serverCount);
            //总工时 总油耗
            Map<String, Object> mapCount = modelDao.selectAverage(reqMap);
            resultMap.put("workHourSum", Orgin.getDoubleValue(mapCount,"workHourSum")*9);
            resultMap.put("fuelSum", Orgin.getDoubleValue(mapCount,"fuelSum")*9);
            //设备数量
            List<Map<String, Object>> carList = modelDao.selectCar(reqMap);
            resultMap.put("carAll",carList.size()*9);
            //在线
            Long status = carList.stream()
                    .filter(o -> Orgin.getIntValue(o, "status") == 1).count();
            resultMap.put("carOnline", status);
            //故障
            Long faultCount = carList.stream()
                    .filter(o -> Orgin.getIntValue(o, "fault_status") == 1).count();
            resultMap.put("faultCount", faultCount*9);
            reqMap.put("status",1);
            List<Map<String, Object>> mapList = modelDao.selectPoints(reqMap);
            for (Map<String, Object> item : mapList) {
                double[] myList = new double[2];
                myList[0]=Orgin.getDoubleValue(item,"GPSlongitude");
                myList[1]=Orgin.getDoubleValue(item,"GPSlatitude");
                item.put("lnglat",myList);
                item.remove("GPSlongitude");
                item.remove("GPSlatitude");
            }
            resultMap.put("onlineCarType1",mapList);
            resultMap.put("onlineCarType1Size",mapList.size()*9);
            reqMap.put("status",2);
            List<Map<String, Object>> mapLis2  = modelDao.selectPoints(reqMap);
            for (Map<String, Object> item : mapLis2) {
                double[] myList1 = new double[2];
                myList1[0]=Orgin.getDoubleValue(item,"GPSlongitude");
                myList1[1]=Orgin.getDoubleValue(item,"GPSlatitude");
                item.put("lnglat",myList1);
                item.remove("GPSlongitude");
                item.remove("GPSlatitude");
            }
            resultMap.put("offlineCarType1",mapLis2);
            resultMap.put("offlineCarType1Size",mapLis2.size()*9);
        }
        return resultMap;
    }

    /**
     * 获取全部车辆实时位置
     * @return
     * @throws MyException
     */
    @Override
    public List<Map<String, Object>> getRealTimeLocation(Map<String, Object> reqMap) throws MyException {
        //用于返回list map
        List<Map<String, Object>> listMap = new ArrayList<>();
        List<Map<String, Object>> allCars = screenDataMapper.getAllCar(reqMap);
        // 获取车辆实时数据
        JSONArray thingsArry = JSONArray
                .parseArray(HttpClient.doGet("https://cloud.zoweunion.com/API/System/MSCS/Facility?type=node" ,
                        "ZOWEUNION", "e82444a08987594e11a55b29fef55ae42f4df9fa"));
        if ( thingsArry != null && thingsArry.size() > 0) {
            for (Map<String, Object> allCar : allCars) {
                String thingsId = allCar.get("things_id").toString();
                for (int i = 0; i < thingsArry.size(); i++) {
                    JSONObject things = (JSONObject) thingsArry.get(i);
                    if (thingsId.equals(things.getString("NodeTag"))){
                        Map<String, Object> map = new HashMap<>(16);
                        map.put("info", thingsId);
                        map.put("lng", things.getString("Longitude"));
                        map.put("lat", things.getString("Latitude"));
                        listMap.add(map);
                        break;
                    }
                }

            }
        }
        return listMap;
    }

    /**
     * 获取全部车辆前2条历史数据
     * @return
     * @throws MyException
     */
    @Override
    public List<Map<String, Object>> getRealTimeHistoryLocation(Map<String, Object> reqMap) throws MyException {
        //用于返回list map
        List<Map<String, Object>> listMap = new ArrayList<>();
        List<Map<String, Object>> allCars = screenDataMapper.getAllCar(reqMap);
        // 获取车辆历史数据
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //当前时间
        String nowtime = sdf.format(new Date());
        //当前时间前一月
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, - 3);
        Date d = c.getTime();
        String day = sdf.format(d);
        String time = null;
        try {
            time = "startTime=" + URLEncoder.encode(day, "utf-8") + "&endTime="
                    + URLEncoder.encode(nowtime, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        StringBuilder opcpathUrl = new StringBuilder();
        opcpathUrl.append(
                Constants.THINGS_HIS_URL + "NodeFullTag=" + "&istree=false&");
        opcpathUrl.append(time);
        JSONObject things = JSONObject.parseObject(HttpClient.doGet(opcpathUrl.toString(),
                "ZOWEUNION", "e82444a08987594e11a55b29fef55ae42f4df9fa"));
        if (things.size() > 0) {
            JSONArray carArry = (JSONArray) things.get("node");
            if (null != carArry && carArry.size() > 0) {
                for (Map<String, Object> allCar : allCars) {
                    String thingsId = allCar.get("things_id").toString();
                    for (int i = 0; i < carArry.size(); i++) {
                        JSONObject nodeData = (JSONObject) carArry.get(i);
                        if (thingsId.equals(nodeData.getString("NodeTag"))){
                            List<Map<String, Object>> datalist = (List<Map<String, Object>>) nodeData.get("datalist");
                            Map<String, Object> map = new HashMap<>(16);
                            if (datalist.size() > 1) {
                                Map<String, Object> lastData = datalist.get(datalist.size()-1);
                                Map<String, Object> lastButOneData = datalist.get(datalist.size()-2);
                                map.put("from", lastButOneData.get("GPSlongitude").toString() + "," + lastButOneData.get("GPSlatitude").toString());
                                map.put("to", lastData.get("GPSlongitude").toString() + "," + lastData.get("GPSlatitude").toString());
                                listMap.add(map);
                            } else {

                                map.put("from", "0,0");
                                map.put("to", "0,0");
                                listMap.add(map);
                            }
                        }
                    }
                }
            }
        }
         return listMap;
    }

    @Override
    public List<Map<String, Object>> getRealTimeLocationNew(Map<String, Object> reqMap) throws MyException {
        //用于返回list map
        List<Map<String, Object>> listMap = new ArrayList<>();
        List<Map<String, Object>> allCars = screenDataMapper.getAllCar(reqMap);
        for (Map<String, Object> carMap : allCars) {
            String thingsId = carMap.get("id").toString();
            Map<String, Object> pcCarMap = toolCarDataMapper.getPcCar(thingsId);
            if (pcCarMap.get("device_template") == null) {
                throw new MyException(Constants.CODE_HANDEL_FAILED, "此设备尚未配置网关");
            }
            String adviceTemplateId = pcCarMap.get("device_template").toString();
            String tableName = ThingsData.getTableName(adviceTemplateId);
            // 获取车辆最新设备信息
            Map<String, Object> carDataMap = toolCarDataMapper.lastCarData(tableName, thingsId);
            if (carDataMap != null) {
                Map<String, Object> lonMap = new HashMap<>(6);
                lonMap.put("info", thingsId);
                lonMap.put("lng", carDataMap.get("GPSlongitude"));
                lonMap.put("lat", carDataMap.get("GPSlatitude"));
                listMap.add(lonMap);
            }
        }
        return listMap;
    }

    @Override
    public List<Map<String, Object>> getRealTimeHistoryLocationNew(Map<String, Object> reqMap) throws MyException {
        //用于返回list map
        List<Map<String, Object>> listMap = new ArrayList<>();
        List<Map<String, Object>> allCars = screenDataMapper.getAllCar(reqMap);
        // 获取车辆历史数据
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //当前时间
        String nowtime = sdf.format(new Date());
        //当前时间前一月
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, -3);
        Date d = c.getTime();
        String day = sdf.format(d);
        String time = null;

        String startTime = day;
        String endTime = nowtime;

        reqMap.put("startTime", startTime);
        reqMap.put("entTime", endTime);
        this.appPage(reqMap);
        for (Map<String, Object> carMap : allCars) {
            String thingsId = carMap.get("id").toString();
            reqMap.put("thingsId", thingsId);
            Map<String, Object> pcCarMap = toolCarDataMapper.getPcCar(thingsId);
            if (pcCarMap.get("device_template") == null) {
                throw new MyException(Constants.CODE_HANDEL_FAILED, "此设备尚未配置网关");
            }
            String tableName = ThingsData.getTableName(pcCarMap.get("device_template").toString());
            reqMap.put("tableName", tableName);
            // 获取车辆最新设备信息
            List<Map<String, Object>> carDataMap = toolCarDataMapper.dailyLastTwoCarData(reqMap);
            int carDataMapSize = carDataMap.size();
            if (carDataMapSize == 0) {
                Map<String, Object> map = new HashMap<>(4);
                map.put("from", "0,0");
                map.put("to", "0,0");
                listMap.add(map);
                continue;
            }
            for (int i = 0; i < carDataMapSize - 1; i++) {
                Map<String, Object> map = new HashMap<>(4);
                map.put("from", carDataMap.get(i + 1).get("GPSlongitude").toString() + "," + carDataMap.get(i + 1).get("GPSlatitude").toString());
                map.put("to", carDataMap.get(i).get("GPSlongitude").toString() + "," + carDataMap.get(i).get("GPSlatitude").toString());
                listMap.add(map);
            }
        }
        return listMap;
    }

    @Override
    public List<Map<String, Object>> getRealTimeLocationAllCar() throws MyException {
        /*List<Map<String, Object>> carDataList = screenDataMapper.getRealTimeLocationAllCar(new HashMap<>());
        List<Map<String, Object>> resultMapList = new LinkedList<>();
        Map<String, Object> resultMap;
        for (Map<String, Object> carData : carDataList) {
            resultMap = new HashMap<>();
            if (carData.get("things_id") == null || carData.get("device_template") == null) {
                continue;
            }
            String thingsId = carData.get("things_id").toString();
            String deviceTemplate = carData.get("device_template").toString();

//            Map<String, Object> carDataMap = screenDataMapper.getLastCarData(ThingsData.getTableName(deviceTemplate), thingsId);
            Map<String, Object> carDataMap = screenDataMapper.getLastCarData(ThingsData.getTableName(deviceTemplate), thingsId);
            if (carDataMap == null) {
                continue;
            }
            if (carDataMap.get("GPSlatitude") == null || carDataMap.get("GPSlongitude") == null) {
                continue;
            }
            resultMap.put("lat", carDataMap.get("GPSlatitude").toString());
            resultMap.put("lng", carDataMap.get("GPSlongitude").toString());
            resultMap.put("info", thingsId);
            resultMapList.add(resultMap);
        }*/
        return screenDataMapper.getLastCarDataStatistics();
    }
}
